import data from "./regionData";

// 判断是否为空数组
export const isEmptyArray = (arr) => {
    if (!arr)
        return true
    if (arr instanceof Array) {
        return arr.length <= 0
    }
    return true
}

// 把条目加入Map
export const addMapItem = (arr, node) => {
    arr.set(node, node)
}

// 删除Map中条目
export const delMapItem = (map, node) => {
    if (map.has(node)) {
        map.delete(node)
    }
}

// 生成树数据的map
/**
 * [generateTreeDataMap 检查子节点的选中情况]
 * @method generateTreeDataMap
 * @param  {[Object]}   parent              [父节点]
 * @param  {[Array]}    treeData            [源数据]
 * @param  {[Object]}   defaultConfig       [配置]
 * @param  {[Map]}      initCheckedList     [初始化勾选列表]
 * @param  {[Map]}      _checkedList        [勾选列表]
 * @param  {[number]}   level               [展开级别]
 * @param  {[Object]}   _map                [以ID为键值的Hash表]
 * @param  {[Array]}    _idList             [所有的idList]
 * @param  {[Array]}    _renderIdList       [渲染的IdList]
 * @return {[Object]}               
 *
 */
// export const generateTreeDataMap = ( treeData, _map = {},_level=-1,_rootIndex=-1,_parentIndex=-1,_subParentIndex=-1,_index=-1) => {
//     const map = _map

//     let level=++_level;
//     let index = _index;
//     let subParentIndex = _subParentIndex;
//     let parentIndex = _parentIndex;
//     let rootIndex = _rootIndex;
//     treeData.forEach((item, idx) => {
//         const _value = item.Id;
//         if (map[_value]) {
//             throw new Error('The value must be unique')
//         }

//         if(level==1){           
//             //rootIndex=parentIndex;            
//             parentIndex=subParentIndex;
//             subParentIndex=index;
//         }
//         if(level==2){          
//             // parentIndex=subParentIndex;
//             // subParentIndex=index;

//             // if(!item.Child||!item.Child.length){
//             //     parentIndex=subParentIndex;
//             //     //subParentIndex=index;                  
//             // }else{
//             //     parentIndex=subParentIndex;
//             //     subParentIndex=index;  
//             // }

//             parentIndex=subParentIndex;
//                 subParentIndex=index; 
//         }
//         if(level==3){
//             rootIndex=parentIndex;
//             parentIndex=subParentIndex;
//             //rootIndex=parentIndex;
//              subParentIndex=index;
//             //subParentIndex=_parentIndex;            
//         }
//         map[_value] = {
//             ...item,
//             level:level,
//             rootIndex,
//             parentIndex,
//             subParentIndex,
//             index:idx,
//         }
//         if (item.Child&&item.Child.length) {
//             map[_value].Child = item
//                 .Child
//                 .map((_item) => _item.Id)
//             // generateTreeDataMap(item, item.Child, defaultConfig, initCheckedList, checkedList, top, rootIndex, _level + 1, map, idList, renderIdList)
//             generateTreeDataMap(item.Child,map,level,rootIndex,parentIndex,subParentIndex,idx)
//         }
//     })
//     return { map }
// }



export const generateTreeDataMap = (treeData, _map = {}, _level = -1, _rootIndex = -1, _parentIndex = -1, _subParentIndex = -1) => {
    const map = _map

    let level = ++_level;
    //let index = _index;
    let subParentIndex = _subParentIndex;
    let parentIndex = _parentIndex;
    let rootIndex = _rootIndex;
    treeData.forEach((item, idx) => {
        const _value = item.Id;
        if (map[_value]) {
            throw new Error('The value must be unique')
        }

        map[_value] = {
            ...item,
            level: level,
            rootIndex,
            parentIndex,
            subParentIndex,
            index: idx,
        }
        if (item.Child && item.Child.length) {
            map[_value].Child = item
                .Child
                .map((_item) => _item.Id)
            // generateTreeDataMap(item, item.Child, defaultConfig, initCheckedList, checkedList, top, rootIndex, _level + 1, map, idList, renderIdList)
            generateTreeDataMap(item.Child, map, level, _parentIndex, _subParentIndex, idx)
        }
    })
    return map 
}



/**
 * [childCheckedStatus 检查子节点的选中情况]
 * @method childCheckedStatus
 * @param  {[Array]}    children        [节点的子节点集合]
 * @param  {[HashMap]}  TreeDataMap     [以ID为键值的Hash表]
 * @param  {[Object]}   checkbox        [配置]
 * @return {[Object]}                   [节点的选中状态]
 *
 */
export const childCheckedStatus = (children, TreeDataMap, checkbox) => {
    // 子级节点被全部选中影响父级节点半选
    const { halfChain } = checkbox

    // 默认父节点选中
    let checked = true;
    // 半选默认为false
    let halfChecked = false;


    children.forEach((item) => {
        const { checkStatus } = TreeDataMap[item];
        // 该节点的半选或者勾选为true 
        if (checkStatus.halfChecked || checkStatus.checked) {
            halfChecked = true;
        }
        // 有一个节点的勾选为false
        if (!checkStatus.checked) {
            checked = false;
        }
    })
    return { checked, halfChecked };
}

/**
 * [parentChain 设置父节点checkbox状态]
 * @method parentChain
 * @param {[HashMap]} TreeDataMap  [以ID为键值的Hash表，方便快速查找]
 * @param {[Object]}  parentNode   [父节点]
 * @param {[Object]}  config       [配置]
 * @param {[Array]}   checkedList  [选中复选框的Value列表]]]
 * @return {[null]}   null
 */
export const parentChain = (TreeDataMap, parentNode, config, checkedList) => {
    if (parentNode) {
        const checkStatus = childCheckedStatus(parentNode.Child, TreeDataMap, config)
        Object.assign(parentNode, { checkStatus });

        // 加入/移除 选中的父节点Value列表
        if (checkStatus.checked) {
            addMapItem(checkedList, parentNode.Id)
        } else {
            delMapItem(checkedList, parentNode.Id)
        }

        // 递归
        if ("undefined" !== typeof parentNode.Pid) {
            parentChain(TreeDataMap, TreeDataMap[parentNode.Pid], config, checkedList);
        }
    }
}

/**
 * [childrenChain 设置子节点的checkbox状态]
 * @method childrenChain
 * @param {[HashMap]} 	TreeDataMap 	[以ID为键值的Hash表]
 * @param {[Array]} 	children 	[子节点数组]
 * @param {[bool]}  	checked  	[checkbox状态]
 * @param {[Array]}  	checkedList  	[选中复选框的Value列表]]]
 * @return {[null]}     null
 */
export const childrenChain = (TreeDataMap, children, checked, checkedList) => {
    if (!children) {
        // console.log('子节点不存在')
        return
    }
    children.forEach((id) => {
        let node = TreeDataMap[id];
        if (node.disabled) {
            // 被禁用的无法选中 return
        } else {
            node.checkStatus = {
                checked: checked,
                halfChecked: false
            }

            if (checked) {
                if (node.Pid !== 0 && !TreeDataMap[node.Pid].checkStatus.checked) {
                    addMapItem(checkedList, node.Id)
                }

            } else {
                delMapItem(checkedList, node.Id)
            }
        }
        if (node.Child) {
            childrenChain(TreeDataMap, node.Child, checked, checkedList);
        }
    })
}

/**
 * [findAllChildren 查找指定的所有子节点]
 * @method findAllChildren
 * @param  {[Array]}   children     [子节点集合]
 * @param  {[HashMap]} TreeDataMap  [以ID为键值的Hash表，方便快速查找]
 * @param  {[Array]}  _arr          [递归返回值]
 * @return {[Array]}  arr          [子节点数组]
 *
 */
export const findAllChildren = (children, treeDataMap, _arr = []) => {
    const arr = _arr
    children.forEach((item) => {
        const _item = treeDataMap[item]
        arr.push(item)
        if (!isEmptyArray(_item.Child)) {
            findAllChildren(_item.Child, treeDataMap, arr)
        }
    })
    return arr
}

/**
 * [filterListCheckChildren 搜索功能-过滤列表ID的子节点是否满足搜索条件]
 * @method filterListCheckChildren
 * @param  {[Array]}   _children     [子节点集合]
 * @param  {[HashMap]} treeDataMap   [以ID为键值的Hash表，方便快速查找]
 * @param  {[String]]}  val          [搜索条件]
 * @return {[Boolean]}               [true-满足 / false-不满足]
 *
 */
export const filterListCheckChildren = (_children, treeDataMap, val) => {
    return _children.some((item) => {
        const { title, value, children } = treeDataMap[item];
        if (title.indexOf(val) > -1) {
            return true
        }
        if (!isEmptyArray(children)) {
            return filterListCheckChildren(children, treeDataMap, val)
        }
        return false
    })
}

/**
 * [getFilterIdList 获取根据搜索条件过滤的id列表]
 * @method getFilterIdList
 * @param  {[Array]}    idList                   [源集合]
 * @param  {[HashMap]}  treeDataMap              [以ID为键值的Hash表，方便快速查找]
 * @param  {[String]}   val                      [搜索条件]
 * @param  {[Array]}    filterIdList             [过滤后的列表]
 * @return {[Array]}    _filterIdList
 *
 */
export const getFilterIdList = (idList, treeDataMap, val, filterIdList = [], ) => {
    let _filterIdList = filterIdList;
    idList.forEach((item) => {
        const { title, value, children, parentVal } = treeDataMap[item];

        if (title.indexOf(val) > -1 || (!isEmptyArray(children) && filterListCheckChildren(children, treeDataMap, val))) {
            // console.log(value)

            if (parentVal) {
                // 父级展开isExpand
                treeDataMap[parentVal] = {
                    ...treeDataMap[parentVal],
                    isExpand: true
                }
            }
            return _filterIdList.push(value)
        }
    })
    return _filterIdList
}

/**
 * [treeDataMapCheckRenderIdList 根据treeDataMap检查RenderIdList中是否有父级不展开的情况]
 * @method treeDataMapCheckRenderIdList
 * @param  {[HashMap]}  treeDataMap             [以ID为键值的Hash表，方便快速查找]
 * @param  {[Array]}    renderIdList            [渲染的IdList]
 * @return {[Array]}    _renderIdList
 *
 */
export const treeDataMapCheckRenderIdList = (treeDataMap, renderIdList) => {
    const _renderIdList = renderIdList.filter((id) => {
        const parentVal = treeDataMap[id] && treeDataMap[id].Pid
        if (parentVal) {
            const parentItem = treeDataMap[parentVal];
            if (parentItem && !parentItem.isExpand) {
                return false
            }
        }
        return true
    })
    return _renderIdList
}

/**
 * [checkedCheckedList 根据checkedList检查树种的勾选]
 * @method checkedCheckedList
 * @param  {[HashMap]}  treeDataMap             [以ID为键值的Hash表，方便快速查找]
 * @param  {[Array]}    checkedList             [勾选的IdList]
 * @return {[Object]}    checkbox               [配置]
 *
 */
export const checkedCheckedList = (treeDataMap, checkedList, checkbox) => {

    // 检查checked的List
    checkedList.forEach((value) => {
        const treeItem = treeDataMap[value]
        const parentVal = treeItem.parentVal
        checkbox.parentChain && parentVal && _parentChain(treeDataMap, treeDataMap[parentVal], checkbox, checkedList)
    })
}

/**
 * [_parentChain 初始化时设置父节点checkbox状态]
 * @method _parentChain
 * @param {[HashMap]} treeDataMap  [以ID为键值的Hash表，方便快速查找]
 * @param {[Object]}  parentNode   [当前节点]
 * @return {[null]}   null
 */
export const _parentChain = (treeDataMap, parentNode) => {
    if (parentNode) {
        const isHalf = parentNode.Child.some((item) => {
            const currentNode = treeDataMap[item]
            if (currentNode.checkStatus.checked || currentNode.checkStatus.halfChecked) {
                return true
            }
            return false
        })
        parentNode.checkStatus.halfChecked = isHalf
        // 递归
        if ("undefined" !== typeof parentNode.parentVal) {
            _parentChain(treeDataMap, treeDataMap[parentNode.parentVal]);
        }
    }
}


export const getCheckedCount = (item, treeDataMap, count = 0) => {
    if (item.Child) {
        item.Child.forEach((value, index) => {
            count = count + getChildCheckedCount(treeDataMap[value], treeDataMap)
        })
    }
    return count
}
export const getChildCheckedCount = (data, treeDataMap) => {
    let count = 0

    if (data.Child) {
        data.Child.forEach((value, index) => {
            if (treeDataMap[value].checkStatus.checked) {
                count = count + 1
            }
            if (treeDataMap[value].Child) {
                getChildCheckedCount(treeDataMap[value].Child);
            }
        })
    } else {
        if (data.checkStatus.checked) {
            count = count + 1
        }



    }

    return count;
}